package com.mengya.cas;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * @ClassName ABADemo
 * @Description
 * @Author xiongwei.wu
 * @Date 2023/1/16 17:12
 **/
public class ABADemo {
    static AtomicInteger atomicInteger = new AtomicInteger(100);
    static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(100, 1);

    public static void main(String[] args) {
        new Thread(() -> {
            int stamp = atomicStampedReference.getStamp();
            System.out.println(Thread.currentThread().getName() + "\t --------默认版本号：" + stamp);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException exception) {
                exception.printStackTrace();
            }
            atomicStampedReference.compareAndSet(100, 101, stamp, stamp + 1);
            System.out.println(Thread.currentThread().getName() + "\t --------1次版本号：" + atomicStampedReference.getStamp());
            atomicStampedReference.compareAndSet(101, 100, atomicStampedReference.getStamp(), 102);
            System.out.println(Thread.currentThread().getName() + "\t --------2次版本号：" + atomicStampedReference.getStamp());
        }, "t3").start();

        new Thread(() -> {
            int stamp = atomicStampedReference.getStamp();
            System.out.println(Thread.currentThread().getName() + "\t --------默认版本号：" + stamp);
            //让前面的T3完成ABA问题
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException exception) {
                exception.printStackTrace();
            }
            boolean b = atomicStampedReference.compareAndSet(100, 20230116, stamp, stamp + 1);
            System.out.println(Thread.currentThread().getName() + "\t -------操作成功否：" + b);
        }, "t4").start();
    }

    private static void abaProblem() {
        new Thread(() -> {
            atomicInteger.compareAndSet(100, 101);
            atomicInteger.compareAndSet(101, 100);
        }, "t1").start();

        try {
            TimeUnit.MILLISECONDS.sleep(10);
        } catch (InterruptedException exception) {
            exception.printStackTrace();
        }

        new Thread(() -> {
            boolean b = atomicInteger.compareAndSet(100, 20230116);
            System.out.println(Thread.currentThread().getName() + "\t 修改成功否：" + b + "\t" + atomicInteger.get());
        }, "t2").start();
    }
}
